#include "PreCompile.hpp"
#include "IfDirective.hpp"
#include "Expression.hpp"

namespace CPreProc
{
  typedef std::string ParseError;

  Glib::RefPtr<IfCondition> IfCondition::parse(Tokenizer &tokenizer)
  {
    return Glib::RefPtr<IfCondition>(new IfCondition(tokenizer));
  }

  IfCondition::IfCondition(Tokenizer &tokenizer)
  {
    tokenizer.skip_optional_whitespace();

    condition_begin = tokenizer.get_cur_ptr();
    tokenizer.move_to_end();
    condition_end = tokenizer.get_cur_ptr();
  }

  bool IfCondition::evaluate(PreProcessorContext &context)
  {
    BuildNG::StringBuilder<2048> macroed;

    apply_macros(condition_begin,condition_end,macroed,context);

    const gchar *macroed_begin = macroed.get_begin();
    const gchar *macroed_end = macroed.get_end();

    Expression expression;
    expression.parse(macroed_begin,macroed_end);

    ExpressionValue result = expression.evaluate();
    if(result.type != ExpressionValue::Type_Int)
      throw ParseError("The expression following the #if directive must be an integer expresion.");

    return result.int_value != 0;
  }

  void IfCondition::load(BuildNG::InStream &src)
  {
    assert(!"not implemented yet");
  }

  void IfCondition::save(BuildNG::OutStream &out)
  {
    assert(!"Not implemented yet");
  }
}

